using System;
using System.Collections.ObjectModel;
using GersonLehrman.Experts.UnitTests.TestingStuff.Specifications;
using GersonLehrman.Experts.UnitTests.TestingStuff.View;
using MvpFramework;
using MvpFramework.Infastructure;
using MvpFramework.Specifications;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;

namespace GersonLehrman.Experts.UnitTests.Infrastructure
{
    [TestFixture]
    public class SpecificationFactoryTestFixture : AssertionHelper
    {
        private SpecificationFactory _factory;
        private ReadOnlyCollection<Specification<ISomeThingToDoView>> _results;
        private MockRepository _mocker;

        public void Arrange()
        {
            _mocker = new MockRepository();

            var specs = new Collection<Specification<ISomeThingToDoView>>
                            {
                                new SomthingToDoValidator(),
                                new SomethingElseToDoValidator()
                            };
        }

        public void Act()
        {
            _mocker.ReplayAll();
            _factory = new SpecificationFactory();

            _results = _factory.GetSpecificationsFor<ISomeThingToDoView>();
        }

        private void Assert()
        {
            _mocker.VerifyAll();
            Expect(_results.Count, Is.EqualTo(2));
            Expect(_results[0].GetType() == typeof (SomthingToDoValidator) ||
                   _results[0].GetType() == typeof (SomethingElseToDoValidator));
            Expect(_results[1].GetType() == typeof (SomthingToDoValidator) ||
                   _results[1].GetType() == typeof (SomethingElseToDoValidator));
        }

        [Test]
        public void view_validation_factory_finds_all_specifications_for_view()
        {
            Arrange();
            Act();
            Assert();
        }
    }
}

namespace GersonLehrman.Experts.UnitTests
{
    namespace TestingStuff.View
    {
        public interface ISomeThingToDoView:IMvpView
        {
        }

        public class SomethingToDo : ISomeThingToDoView
        {
            public bool IsInitialLoad
            {
                get { return true; }
            }
        }
    }

    namespace TestingStuff.Specifications
    {
        public class SomthingToDoValidator : Specification<ISomeThingToDoView>
        {
            public override bool IsSatisfiedBy(ISomeThingToDoView obj)
            {
                throw new NotImplementedException();
            }
        }

        public class SomethingElseToDoValidator : Specification<ISomeThingToDoView>
        {
            public override bool IsSatisfiedBy(ISomeThingToDoView obj)
            {
                throw new NotImplementedException();
            }
        }
    }
}